package core.util;

import java.io.*;

public class IndentWriter extends Writer {

	public static final int DEFAULT_INDENT_SIZE = 4;

	private Writer out;

	private int indentCount =0;

	private char[] indentSpaces;

	private boolean  newLineFlag = true;

	private boolean useTab = false;

	public IndentWriter( Writer out ) {
		this.out = out;
		this.indentSpaces = new char[ DEFAULT_INDENT_SIZE ];
		for ( int i=0; i < this.indentSpaces.length; i++ ) {
			indentSpaces[i] = ' ';
		}
	}

	public IndentWriter( Writer out, boolean useTab ) {
		this.out = out;
		this.useTab = useTab;
		if ( this.useTab == false ) {
			this.indentSpaces = new char[ DEFAULT_INDENT_SIZE ];
			for ( int i=0; i < this.indentSpaces.length; i++ ) {
				indentSpaces[i] = ' ';
			}
		}
	}

	public IndentWriter( Writer out, int indentCount, boolean useTab ) {
		this( out, useTab );
		this.indentCount = indentCount;
	}

	public IndentWriter( Writer out, int indentCount, int indentSize ) {
		this.out = out;
		this.indentCount = indentCount;
		this.indentSpaces = new char[ indentSize ];
		for ( int i=0; i < this.indentSpaces.length; i++ ) {
			indentSpaces[i] = ' ';
		}
	}

	private void writeIndent() throws java.io.IOException {
		for ( int i=0; i < indentCount; i++ ) {
			if ( useTab == false ) {
				out.write( indentSpaces );
			}
			else {
				out.write( '\t' );
			}
		}
	}

	public void write(char[] buf, int off, int len) throws java.io.IOException {
		if ( newLineFlag == true ) {
			writeIndent();
			newLineFlag = false;
		}

		int i, last;

		for ( i=0, last=0; i < len; i++ ) {
			if ( buf[i+off] == '\n' ) {
				out.write( buf, off+last, i+1-last );
				last = i+1;

				if ( i == (len-1) ) {
					newLineFlag = true;
					return;
				}

				writeIndent();
			}
		}

		out.write( buf, off+last, len-last );
	}

	public void flush() throws java.io.IOException {
		out.flush();
	}

	public void close() throws java.io.IOException {
		out.close();
	}

	public void indent( int count ) throws java.io.IOException {
		indentCount += count;
	}

	public void indentIn() throws java.io.IOException {
		indent( 1 );
	}

	public void indentOut() throws java.io.IOException {
		indent( -1 );
	}

	public int getIndentCount() {
		return indentCount;
	}

	public void setIndentCount(int indentCount) {
		this.indentCount = indentCount;
	}

	public int getIndentSize() {
		return indentSpaces.length;
	}

	public void setIndentSize( int indentSize ) {
		indentSpaces = new char[ indentSize ];
		for ( int i=0; i < indentSpaces.length; i++ ) {
			indentSpaces[i] = ' ';
		}
	}

	public Writer getOut() {
		return out;
	}

	public void setOut(Writer out) {
		this.out = out;
	}
}